package com.hotchpotch.retrofit;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;

import com.hotchpotch.base.ActivityManager;
import com.hotchpotch.base.AppConstant;
import com.hotchpotch.base.MyApplication;
import com.hotchpotch.util.JsonUtil;
import com.hotchpotch.util.Logg;
import com.hotchpotch.util.ToastUtil;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Created by Administrator on 2017/10/17 0017.
 */

public class RetrofitManager {
    private static RetrofitManager retrofitManager;
    private static Retrofit retrofit;
    private static Context mContext;
    private static List<Call> callList;
    private static Handler handler = new Handler(Looper.getMainLooper());
    private static final String TAG = "RetrofitManager";

    private RetrofitManager() {

    }

    public static RetrofitManager getInstance() {
        if (retrofitManager == null) {
            retrofitManager = new RetrofitManager();
        }
        return retrofitManager;
    }

    public void init(Context context) {
        retrofit = new Retrofit.Builder()
                .baseUrl(AppConstant.test_url2)
                //String转化器
                .addConverterFactory(ScalarsConverterFactory.create())
                //gson转化器
//                .addConverterFactory(GsonConverterFactory.create())
                .client(getOkhttp())
                .build();
        mContext = context;
        callList = new ArrayList<>();
    }

    /**
     * 网络请求接口 的实例
     *
     * @return
     */
    private static RetrofitService getStringService() {
        RetrofitService service = retrofit.create(RetrofitService.class);
        return service;
    }

    /**
     * 配置OkHttpClient
     *
     * @return
     */
    private OkHttpClient getOkhttp() {
        File sdcache = MyApplication.getContext().getExternalCacheDir();//缓存地址
        int cacheSize = 10 * 1024 * 1024;//缓存大小
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .connectTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize))
                .build();
        return okHttpClient;
    }

    /**
     * 异步Get 无回调
     *
     * @param url
     */
    public static void doGet(String url) {
        Call<ResponseBody> mCall = getStringService().doGet(url);
        callList.add(0, mCall);
        execute(mCall);
    }

    /**
     * 异步Post 无回调
     *
     * @param url
     * @param requestBody
     */
    public static void doPost(String url, RequestBody requestBody) {
        Call<ResponseBody> mCall = getStringService().doPost(url, requestBody);
        callList.add(0, mCall);
        execute(mCall);
    }

    /**
     * 异步上传图片 无回调
     *
     * @param url
     * @param pathList
     */
    public static void uploadImgs(String url, List<String> pathList) {
        //        String token = "ASDDSKKK19990SDDDSS";//用户token
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);//表单类型
//                .addFormDataPart(ParamKey.TOKEN, token);//ParamKey.TOKEN 自定义参数key常量类，即参数名
        //多张图片
        for (int i = 0; i < pathList.size(); i++) {
            File file = new File(pathList.get(i));//filePath 图片地址
            RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
            builder.addFormDataPart("imgfile"+i, file.getName(), imageBody);//"imgfile"+i 后台接收图片流的参数名
        }
        List<MultipartBody.Part> parts = builder.build().parts();
        Call<ResponseBody> mCall = getStringService().uploadImgs(url, parts);
        callList.add(0, mCall);
        execute(mCall);
    }

    /**
     * 执行异步  无回调
     *
     * @param call
     */
    private static void execute(Call call) {
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    String jsonStr = response.body().string();
                    Logg.e(ActivityManager.getInstance().currentActivity().getLocalClassName(), "获取的数据 = " + jsonStr);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Logg.e(ActivityManager.getInstance().currentActivity().getLocalClassName(), "onFailure = " + t.getMessage().toString());
                ToastUtil.showToast(t.getMessage().toString());
            }
        });
    }

    /**
     * 异步Get 有回调
     *
     * @param url
     * @param resultCallback
     */
    public static void doGet(String url, final ResultCallback resultCallback) {
        Call<ResponseBody> mCall = getStringService().doGet(url);
        callList.add(0, mCall);
        execute(mCall, resultCallback);
    }

    /**
     * 异步post 有回调
     *
     * @param url
     * @param requestBody
     */
    public static void doPost(String url, RequestBody requestBody, final ResultCallback resultCallback) {
        Call<ResponseBody> mCall = getStringService().doPost(url, requestBody);
        callList.add(0, mCall);
        execute(mCall, resultCallback);
    }

    /**
     * 异步上传图片 有回调
     * @param url
     * @param pathList
     * @param resultCallback
     */
    public static void uploadImgs(String url, List<String> pathList, ResultCallback resultCallback) {
//        String token = "ASDDSKKK19990SDDDSS";//用户token
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);//表单类型
//                .addFormDataPart(ParamKey.TOKEN, token);//ParamKey.TOKEN 自定义参数key常量类，即参数名
        //多张图片
        for (int i = 0; i < pathList.size(); i++) {
            File file = new File(pathList.get(i));//filePath 图片地址
            RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
            builder.addFormDataPart("imgfile"+i, file.getName(), imageBody);//"imgfile"+i 后台接收图片流的参数名
        }
        List<MultipartBody.Part> parts = builder.build().parts();
        Call<ResponseBody> mCall = getStringService().uploadImgs(url, parts);
        callList.add(0, mCall);
        execute(mCall, resultCallback);
    }

    /**
     * 执行异步请求 有回调
     */
    private static void execute(Call call, final ResultCallback resultCallback) {
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    final String jsonStr = response.body().string();
                    Logg.e(ActivityManager.getInstance().currentActivity().getLocalClassName(), "获取的数据 = " + jsonStr);
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (JsonUtil.parseJson(jsonStr, resultCallback.mType) == null) {
                                resultCallback.onFinish();
                                Logg.e(ActivityManager.getInstance().currentActivity().getLocalClassName(), "数据解析异常");
                            } else {
                                resultCallback.onResponse(JsonUtil.parseJson(jsonStr, resultCallback.mType));
                                resultCallback.onFinish();
                            }
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(final Call<ResponseBody> call, final Throwable t) {
                Logg.e(ActivityManager.getInstance().currentActivity().getLocalClassName(), "onFailure = " + t.getMessage().toString());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        resultCallback.onError(call, t);
                        resultCallback.onFinish();
                        if (!t.getMessage().toString().equals("Socket closed")) {
                            if (t.getMessage().toString().contains("Failed to connect to")) {
                                ToastUtil.showToast("请打开您的网络连接！");
                            } else {
                                ToastUtil.showToast(t.getMessage().toString());
                            }
                        }
                    }
                });
            }
        });
    }

    /**
     * 停止请求
     */
    public static void closeCall() {
        if (callList != null && callList.size() > 0) {
            for (Call call : callList) {
                call.cancel();
            }
            callList.clear();
        }
    }
}
